package com.ddpt.platform.common.export.vo;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ddpt.platform.common.base.BaseEntity;
import com.ddpt.platform.common.export.Export;
import lombok.Getter;
import lombok.Setter;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 导出体vo - 父类
 *
 * @author : zhanggsc
 * @Data : 2023/2/27 9:32
 */
@Getter
@Setter
public class QueryDataVo extends BaseEntity {

    protected final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 表头映射 key:字段名称 val：注解
     */
    protected Map<String, Export> exportMap = new HashMap<>();

    @Export(value = "id",isStr = true)
    protected String id;

    @Export(value = "商户id",isStr = true)
    protected Long merchantId;

    @Export(value = "机构id",isStr = true)
    protected Long insId;

    @Export(value = "创建时间",isTime = true)
    protected Long createTime;

    @Export(value = "修改时间",isTime = true)
    protected Long updateTime;

    @Export(value = "是否删除",key = {"0","1"},val = {"未删除","已删除"})
    protected Integer deleted;

    /**
     * 转换
     *
     * @param vos
     * @return
     */
    public List<List<Object>> asVos(List<? extends QueryDataVo> vos, Set<String> fieldList) {
        List<List<Object>> datas = new ArrayList<>(vos.size() + 1);
        Field[] fields = getField(vos.get(0), fieldList);
        datas.add(getFirst(vos.get(0), fields));
        for (int v = vos.size() - 1; v >= 0; v--) {
            QueryDataVo vo = vos.get(v);
            List<Object> list = new ArrayList<>();
            Arrays.stream(fields).forEach(field -> {
                //获取字段的值
                try {
                    Object o = field.get(vo);
                    String name = field.getName();
                    Export export = exportMap.get(name);
                    if(export == null){
                        return;
                    }
                    if (export.isStr() && o != null && !(o instanceof String)) {
                        o = o.toString();
                    } else if (export.isTime() && o != null && o instanceof Long) {
                        o = sdf.format(new Date((Long) o));
                    } else if (export.key().length > 0 && export.val().length > 0) {
                        String[] key = export.key();
                        String[] val = export.val();
                        for (int i = 0; i < key.length; i++) {
                            if(key[i].equals(o = o == null || o instanceof String ? o : o.toString())){
                                o = val[i];
                            }
                        }
                    }
                    list.add(o);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            });
            datas.add(list);
        }
        return datas;
    }

    /**
     * 获取字段
     *
     * @param vo
     * @return
     */
    public Field[] getField(QueryDataVo vo, Set<String> fieldList) {
        Field[] fields1 = vo.getClass().getDeclaredFields();
        if (vo.getClass().getName().equals(QueryDataVo.class.getName())) {
            return fields1;
        }
        Field[] fields2 = QueryDataVo.class.getDeclaredFields();
        if (fields2.length == 0) {
            return fields1;
        }
        Field[] fields = new Field[fields1.length + fields2.length];
        System.arraycopy(fields1, 0, fields, 0, fields1.length);
        System.arraycopy(fields2, 0, fields, fields1.length, fields2.length);
        for (Field field : fields) {
            field.setAccessible(true);
            Export export = field.getAnnotation(Export.class);
            if(export == null){
                continue;
            }
            exportMap.put(field.getName(),export);
        }
        Field[] array;
        if(CollectionUtils.isEmpty(fieldList)){
            array = Arrays.stream(fields).filter(f -> exportMap.containsKey(f.getName())).toArray(Field[]::new);
        }else {
            array = Arrays.stream(fields).filter(f -> fieldList.contains(f.getName())).toArray(Field[]::new);
        }
        return array;
    }

    /**
     * 表头
     * @param voOne
     * @param fields
     * @return
     */
    private List<Object> getFirst(QueryDataVo voOne, Field[] fields) {
        List<Object> first = new ArrayList<>();
        for (Field field : fields) {
            Export export = exportMap.get(field.getName());
            //获取字段的值
            first.add(export == null ? "" : export.value());
        }
        return first;
    }

}

